package com.zbl.service;

import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.util.Cookie;
import com.xuxueli.crawler.XxlCrawler;
import com.xuxueli.crawler.parser.strategy.NonPageParser;
import com.zbl.dto.LoginParam;
import com.zbl.parser.QuanBenUserParser;
import com.zbl.vo.WrapperRequestParam;
import lombok.SneakyThrows;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.*;

/**
 * @Author: zhangjun
 * @Date: 2020/7/30 10:51
 * @Description: 采集非Web页面，如JSON接口等，直接输出响应数据
 */
@Service
public class JsonCrawlerService extends AbstractLoginService{
    Map<String, String> responseCookies = new HashMap<String, String>();

    /**
     * 预登陆，获取登录后cookie信息
     * @param loginParam
     * @return
     * @throws IOException
     * @throws InterruptedException
     */
    public String loginSimulation(LoginParam loginParam) throws IOException, InterruptedException {
        HtmlPage newPage = super.login(loginParam);
        WebClient webClient = super.webClientMaps.get(loginParam.getLoginUrl());
        //查看登录成功后跳转的路径
        System.out.println(">>>>>>>>>>>>>> " + newPage.getUrl().toString());

        Set<Cookie> cookies = webClient.getCookieManager().getCookies();
        for (Cookie c : cookies) {
            //登录成功后，将cookie信息存储到map中，用于访问需要携带登录信息接口地址
            responseCookies.put(c.getName(), c.getValue());
            System.out.print(">>>>>>>>>>>>>> " + c.getName()+":"+c.getValue() + "\n");
        }
        webClient.close();
        return "登录成功";
    }

    /**
     * 爬取 【全本小说】 网个人中心信息
     * @param param
     */
    public void crawlerUserInfo(WrapperRequestParam param) {
        if (!responseCookies.isEmpty()) {
            // 构造爬虫
            XxlCrawler crawler = new XxlCrawler.Builder()
                    .setUrls(param.getUrl())
                    .setCookieMap(responseCookies)
                    .setHeaderMap(param.getHeaderMap())
                    .setPageParser(new QuanBenUserParser()) //自定义解析器
                    .build();
            // 启动
            crawler.start(true);
        }
    }

    public void crawler(WrapperRequestParam param, NonPageParser pageParser) {
        // 构造爬虫
        XxlCrawler crawler = new XxlCrawler.Builder()
                .setUrls(param.getUrl())
                .setCookieMap(param.getCookieMap())
                .setHeaderMap(param.getHeaderMap())
                .setPageParser(pageParser)
                .build();
        // 启动
        crawler.start(true);
        /*if (!responseCookies.isEmpty()) {
            // 构造爬虫
            XxlCrawler crawler = new XxlCrawler.Builder()
                    .setUrls(param.getUrl())
                    .setCookieMap(param.getCookieMap())
                    .setHeaderMap(param.getHeaderMap())
                    .setPageParser(pageParser)
                    .build();
            // 启动
            crawler.start(true);
        }*/
    }

    @SneakyThrows
    public void updateChapter(WrapperRequestParam param) {
        // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();

        //创建post请求
        HttpPost httpPost = new HttpPost("https://www.imooc.com/course/ajaxmediauser/");

        /*
         * 添加请求参数
         */
        // 创建请求参数
        List<NameValuePair> list = new LinkedList<>();
        BasicNameValuePair param1 = new BasicNameValuePair("mid", "1414");
        BasicNameValuePair param2 = new BasicNameValuePair("time", "30");
        BasicNameValuePair param3 = new BasicNameValuePair("learn_time", "420");
        list.add(param1);
        list.add(param2);
        list.add(param3);
        // 使用URL实体转换工具
        UrlEncodedFormEntity entityParam = new UrlEncodedFormEntity(list, "UTF-8");
        httpPost.setEntity(entityParam);

        // 浏览器表示
        httpPost.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36");

        // 设置ContentType(注:如果只是传普通参数的话,ContentType不一定非要用application/json)
        httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");

        //设置cookie
        httpPost.setHeader("Cookie","imooc_uuid=64fa2fb6-2e47-444d-b5b2-c2e6fb91e515; imooc_isnew_ct=1584411433; zg_did=%7B%22did%22%3A%20%22170e647e404a30-0d38290306ba49-4313f6a-1fa400-170e647e405c72%22%7D; imooc_isnew=2; UM_distinctid=1713471c7149a3-06cca96d7a1813-4313f6a-1fa400-1713471c7159ed; zg_f375fe2f71e542a4b890d9a620f9fb32=%7B%22sid%22%3A%201587460314155%2C%22updated%22%3A%201587460314494%2C%22info%22%3A%201587460314157%2C%22superProperty%22%3A%20%22%7B%5C%22%E5%BA%94%E7%94%A8%E5%90%8D%E7%A7%B0%5C%22%3A%20%5C%22%E6%85%95%E8%AF%BE%E7%BD%91%E6%95%B0%E6%8D%AE%E7%BB%9F%E8%AE%A1%5C%22%2C%5C%22Platform%5C%22%3A%20%5C%22web%5C%22%7D%22%2C%22platform%22%3A%20%22%7B%7D%22%2C%22utm%22%3A%20%22%7B%7D%22%2C%22referrerDomain%22%3A%20%22www.baidu.com%22%2C%22zs%22%3A%200%2C%22sc%22%3A%200%2C%22firstScreen%22%3A%201587460314155%7D; IMCDNS=0; PSEID=7cb271263b8d122d95589601ab2ab4f1; isShowwechat=1; Hm_lvt_f0cfcccd7b1393990c78efdeebff3968=1596089748,1596089796,1596089809,1596179873; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%227156571%22%2C%22first_id%22%3A%2217210c538b84a7-0a0bb42d6a561b-4313f6a-2073600-17210c538b9921%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%2C%22%24latest_referrer%22%3A%22%22%7D%2C%22%24device_id%22%3A%2217210c538b84a7-0a0bb42d6a561b-4313f6a-2073600-17210c538b9921%22%7D; loginstate=1; apsid=I1NDBkNDhlMTk3NGNhODQ3NjViY2Y2MTZiYTYxMjEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANzE1NjU3MQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGQzY2IzZmQ5YTE1YzllMjE3ZDQyNWU1YTQ0ODFkNjI3T8kjX648Il8%3DZW; Hm_lpvt_f0cfcccd7b1393990c78efdeebff3968=1596181295; cvde=5f223c29d6591-171");

        // 响应模型
        CloseableHttpResponse response = null;
        try {
            // 由客户端执行(发送)Post请求
            response = httpClient.execute(httpPost);
            // 从响应模型中获取响应实体
            HttpEntity responseEntity = response.getEntity();

            System.out.println("响应状态为:" + response.getStatusLine());
            if (responseEntity != null) {
                System.out.println("响应内容长度为:" + responseEntity.getContentLength());
                System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                // 释放资源
                if (httpClient != null) {
                    httpClient.close();
                }
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}
